package topcbl.taxi;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import topcbl.data.CarState;
import topcbl.net.TaxiService;
import topcbl.util.GPSTracker;
import topcbl.util.HttpConnection;
import topcbl.util.JSONParseDistanceAndTime;
import topcbl.util.PathJSONParser;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

public class WaitTaxiActivity extends FragmentActivity {
	View mRootView;
	TextView tvDistance, tvSpeed, tvTime;
	GoogleMap map;
	SharedPreferences preferences;
	GPSTracker gpsTracker;
	Marker marker;
	TaxiService mService = MainActivity.mBindService.getService();
	LatLng mFirstPlace, mSecondPlace;
	UpdateLastPositionThread updateThead;
	CarState carState;
	String[] mBackData;
	Handler handle = new Handler();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_wait_taxi);
		getWindow().setBackgroundDrawable(new ColorDrawable(10));
		setBroadcast2Close();
		mRootView = findViewById(R.id.rootView);
		FragmentManager myFragmentManager = getSupportFragmentManager();
		SupportMapFragment mySupportMapFragment = (SupportMapFragment) myFragmentManager
				.findFragmentById(R.id.map);
		map = mySupportMapFragment.getMap();

		// find user location firstly
		mFirstPlace = mService.getFirstPlace();
		mSecondPlace = mService.getSecondPlace();
		map.animateCamera(CameraUpdateFactory.newLatLngZoom(mFirstPlace, 16),
				100, null);
		updateMarkerAndPath();
		initButtonAndEvent();
		tvDistance = (TextView) findViewById(R.id.tv1);
		tvSpeed = (TextView) findViewById(R.id.tv2);
		tvTime = (TextView) findViewById(R.id.tv3);
		updateThead = new UpdateLastPositionThread();
		updateThead.start();
	}

	@Override
	protected void onStop() {
		super.onStop();
		mService.setIsShow(false);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK)) {
			finish();
		}
		return true;
	}

	private void setBroadcast2Close() {
		BroadcastReceiver intentFromService = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				finish();
			}
		};
		registerReceiver(intentFromService, new IntentFilter(
				"CloseWaitTaxiIntent"));
	}

	private void initButtonAndEvent() {
		Button btnHurry, btnCancel;
		btnHurry = (Button) findViewById(R.id.btn1);
		btnCancel = (Button) findViewById(R.id.btn2);
		btnHurry.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Toast.makeText(getApplicationContext(), "Thúc dục tài xế",
						Toast.LENGTH_LONG).show();
			}
		});
		btnCancel.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				new CancelTaxiDialog(WaitTaxiActivity.this).show();
			}
		});
	}

	public Marker putMarkerOnMap(double lat, double lon, int logo) {
		if (map != null) {
			MarkerOptions mp = new MarkerOptions();
			mp.position(new LatLng(lat, lon));
			mp.title(getString(R.string.markertext));
			mp.icon(BitmapDescriptorFactory.fromResource(logo));
			return map.addMarker(mp);
		}
		return null;
	}

	// ====== draw path on the map ======

	public void drawPath(LatLng frompos, LatLng topos) {
		String url = getMapsApiDirectionsUrl(frompos, topos);
		ReadTask downloadTask = new ReadTask();
		downloadTask.execute(url);
	}

	private String getMapsApiDirectionsUrl(LatLng frompos, LatLng topos) {
		String waypoints = "waypoints=optimize:true|" + frompos.latitude + ","
				+ frompos.longitude + "|" + "|" + topos.latitude + ","
				+ topos.longitude;
		String sensor = "sensor=false";
		String params = waypoints + "&" + sensor;
		String output = "json";
		String url = "https://maps.googleapis.com/maps/api/directions/"
				+ output + "?" + params;
		return url;
	}

	private class ReadTask extends AsyncTask<String, Void, String> {
		@Override
		protected String doInBackground(String... url) {
			String data = "";
			try {
				HttpConnection http = new HttpConnection();
				data = http.readUrl(url[0]);
			} catch (Exception e) {
				Log.d("Background Task", e.toString());
			}
			return data;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			new ParserTask().execute(result);
		}
	}

	private class ParserTask extends
			AsyncTask<String, String, List<List<HashMap<String, String>>>> {

		@Override
		protected List<List<HashMap<String, String>>> doInBackground(
				String... jsonData) {

			JSONObject jObject;
			List<List<HashMap<String, String>>> routes = null;

			try {
				// draw path
				jObject = new JSONObject(jsonData[0]);
				PathJSONParser parser = new PathJSONParser();
				routes = parser.parse(jObject);
				// get distance and time
				JSONParseDistanceAndTime distime = new JSONParseDistanceAndTime(
						jsonData[0]);
				mBackData = distime.parse();
				handle.post(new Runnable() {
					@Override
					public void run() {
						if (mBackData != null) {
							tvDistance.setText("Khoảng cách: " + mBackData[0]);
							tvTime.setText("Thời gian đến: " + mBackData[1]);
						}
					}
				});
			} catch (Exception e) {
				e.printStackTrace();
			}
			return routes;
		}

		@Override
		protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
			ArrayList<LatLng> points = null;
			PolylineOptions polyLineOptions = null;

			// traversing through routes
			for (int i = 0; i < routes.size(); i++) {
				points = new ArrayList<LatLng>();
				polyLineOptions = new PolylineOptions();
				List<HashMap<String, String>> path = routes.get(i);

				for (int j = 0; j < path.size(); j++) {
					HashMap<String, String> point = path.get(j);
					double lat = Double.parseDouble(point.get("lat"));
					double lng = Double.parseDouble(point.get("lng"));
					LatLng position = new LatLng(lat, lng);
					points.add(position);
				}

				polyLineOptions.addAll(points);
				polyLineOptions.width(6);
				polyLineOptions.color(getResources().getColor(
						R.color.orange_trans));
			}
			map.addPolyline(polyLineOptions);
		}
	}

	public void updateMarkerAndPath() {
		if (mFirstPlace != null && mSecondPlace != null) {
			map.clear();
			marker = putMarkerOnMap(mFirstPlace.latitude,
					mFirstPlace.longitude, R.drawable.user_pin);
			putMarkerOnMap(mSecondPlace.latitude, mSecondPlace.longitude,
					R.drawable.taxi_pin_1);
			drawPath(mFirstPlace, mSecondPlace);
			marker.showInfoWindow();
		} else {
			Toast.makeText(this, "Lỗi xác định địa điểm trên service",
					Toast.LENGTH_LONG).show();
		}
	}

	public class UpdateLastPositionThread extends Thread {

		@Override
		public void run() {
			while (!Thread.currentThread().isInterrupted()) {
				carState = mService.getLastPosition();
				handle.post(new Runnable() {
					@Override
					public void run() {
						if (carState != null) {
							mSecondPlace = new LatLng(carState.getLat(),
									carState.getLng());
							updateMarkerAndPath();
							tvSpeed.setText("Tốc độ: " + carState.getSpeed()
									+ "km/h");
						} else {
							//do nothing
						}
					}
				});

				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}
}
